package demo.web;

import demo.SpringBoot2App;
import demo.vo.common.ApiResult;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.Objects;

@RestController
@RequestMapping("/sys/log/level")
public class SysLogLevelController {

    private static final Logger log = LoggerFactory.getLogger(DemoRestController.class);

    ILoggerFactory loggerContext = LoggerFactory.getILoggerFactory();

    /**
     * 测试当前日志等级接口
     *
     * @param packageName 包名
     * @return ApiResult               返回结果
     * 栗子:
     * curl [baseUrl]/sys/log/level/test
     */
    @GetMapping("/test")
    public ApiResult testLevel(String packageName) {
        log.trace("trace");
        log.debug("debug");
        log.info("info");
        log.warn("warn");
        log.error("error");

        StringBuilder msg = new StringBuilder();
        //全局日志等级 + 项目日志等级 + 具体包的日志等级
        msg.append(getLogger("root"));
        msg.append(getLogger(SpringBoot2App.class.getPackage().getName()));
        if (packageName != null && !packageName.isEmpty()) {
            msg.append(getLogger(packageName));
        }
        return ApiResult.success(msg.toString());
    }

    /**
     * 修改日志级别接口
     *
     * @param level 日志级别
     * @return ApiResult               返回结果
     * 栗子:
     * curl [baseUrl]/sys/log/level/info/[包名]
     * curl [baseUrl]/sys/log/level/debug/[包名]
     */
    @GetMapping("/{level}/{packageName}")
    public ApiResult changeLevel(@PathVariable String level,
                                 @PathVariable String packageName) {
        return ApiResult.success(setLogger(packageName, level));
    }

    /**
     * 修改日志级别接口
     *
     * @param level 日志级别
     * @return ApiResult               返回结果
     * 栗子:
     * curl [baseUrl]/sys/log/level/info/[包名]
     * curl [baseUrl]/sys/log/level/debug/[包名]
     */
    @GetMapping("/change")
    public ApiResult changeLogLevel(@RequestParam("level") String level,
                                    @RequestParam("packageName") String packageName) {
        return ApiResult.success(setLogger(packageName, level));
    }

    /**
     * 修改日志级别接口
     *
     * @param level 日志级别
     * @return ApiResult               返回结果
     * 栗子:
     * curl [baseUrl]/sys/log/level/info
     * curl [baseUrl]/sys/log/level/debug
     */
    @GetMapping("/{level}")
    public ApiResult changeLevel(@PathVariable String level) {
        return ApiResult.success(setLogger("root", level));
    }


    /**
     * 获取指定包日志级别             封装[设置日志级别+封装返回值信息]
     *
     * @param packageName 包名
     * @return String               日志级别信息
     */
    private String getLogger(String packageName) {
        return packageName + "日志等级为:" + getLevel(packageName);
    }

    /**
     * 设置指定包日志级别             封装[日志级别检测+设置日志级别+封装返回值信息]
     *
     * @param packageName 包名
     * @return String               日志级别信息
     */
    private String setLogger(String packageName, String level) {
        boolean isAllowed = isAllowed(level);
        if (isAllowed) {
            setLevel(packageName, level);
        }
        return isAllowed
                ? packageName + "日志等级更改为:" + level
                : packageName + "日志等级修改失败,可用值[ERROR,WARN,INFO,DEBUG,TRACE]";
    }

    /**
     * 获取制定包的日志级别
     *
     * @param packageName 包名
     * @return String               日志级别
     */
    private String getLevel(String packageName) {
        Logger logger = loggerContext.getLogger(packageName);
        return logger.getName() + ":" + logger.isInfoEnabled();
    }

    private boolean hasNull(Object... objects) {
        if (Objects.nonNull(objects)) {
            for (Object element : objects) {
                if (null == element) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 设置制定包的日志级别
     *
     * @param packageName 包名
     * @param level       日志等级
     */
    private void setLevel(String packageName, String level) {
        loggerContext.getLogger(packageName);
    }

    //    final String[] levels = {"ERROR","WARN","INFO","DEBUG","TRACE"};
    final String[] levels = {"OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL"};

    /**
     * 判断是否是合法的日志级别
     *
     * @param level 日志等级
     * @return boolean
     */
    private boolean isAllowed(String level) {
        return Arrays.asList(levels).contains(level.toUpperCase());
    }
}
